/*
 * PodioRenderJ3D.java
 *
 * Created on 24 de abril de 2007, 10:10 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

import java.awt.*;
import javax.vecmath.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.ColorCube;

/**
 *
 * @author William Santamaria
 */
public class PodioRenderJ3D extends Container{
    
//     protected SimpleUniverse universo = null;
     protected Component componente_ventana = null;
     protected Canvas3D lienzo3d = null;
     protected BranchGroup escenario = null;
     protected PodioBehavior pb;
    
    /** Creates a new instance of PodioRenderJ3D */
    public PodioRenderJ3D() {
        
        setLayout(new BorderLayout());

        GraphicsConfiguration configuracion;
        configuracion = SimpleUniverse.getPreferredConfiguration();
        lienzo3d = new Canvas3D(configuracion);
		
        BranchGroup scene = createSceneGraph();
	scene.compile();

        SimpleUniverse simpleU = new SimpleUniverse(lienzo3d);
        simpleU.getViewingPlatform().setNominalViewingTransform();
        simpleU.addBranchGraph(scene);

        componente_ventana = lienzo3d;
        lienzo3d.setSize(360, 480);

        this.add( "Center", componente_ventana );
    }

    public BranchGroup createSceneGraph() {
	BranchGroup objRoot = new BranchGroup();
		
        TransformGroup vistaPodio = new TransformGroup();
        vistaPodio.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        vistaPodio.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

	objRoot.addChild(vistaPodio);

//	vistaPodio.addChild( new ColorCube(0.3) );

	vistaPodio.addChild( crearReticula(0) );

	Shape3D cono = crearCono(6.05,2.5,6.55);
        Appearance ap = new Appearance();
	PolygonAttributes pa = new PolygonAttributes();
	pa.setBackFaceNormalFlip(true);
	pa.setCullFace(PolygonAttributes.CULL_NONE);
	ap.setPolygonAttributes(pa);
        TransparencyAttributes transparencia = new TransparencyAttributes(TransparencyAttributes.BLENDED, 0.4f);
        ap.setTransparencyAttributes(transparencia);
	cono.setAppearance(ap);
	vistaPodio.addChild( cono );

        Podio pod = new Podio(66,  GeometryArray.COORDINATES
                                      | GeometryArray.COLOR_3
                                       , 208);
        pod.setCapability(IndexedGeometryArray.ALLOW_COORDINATE_WRITE);
	Shape3D s3d = new Shape3D( pod );
	vistaPodio.addChild( s3d );
		
        AmbientLight lightA = new AmbientLight();
        lightA.setInfluencingBounds(new BoundingSphere());
        vistaPodio.addChild(lightA);
	
	Transform3D camaraPodio = new Transform3D();
        camaraPodio.lookAt(new Point3d(15,9,0), new Point3d(0,4,0), new Vector3d(0,1,0));
	vistaPodio.setTransform(camaraPodio);

        pb = new PodioBehavior(pod);
        pb.setSchedulingBounds(new BoundingSphere());
        objRoot.addChild(pb);
        
        objRoot.compile();

	return objRoot;
    }
    
    public Shape3D crearCono(double radsup, double radinf, double alt){
        IndexedQuadArray cono = new IndexedQuadArray(720, GeometryArray.COORDINATES
                                            | GeometryArray.COLOR_3, 1444);
		for( int i=0; i<360; i++ ){
			cono.setCoordinate( 2*i, new Point3d( radinf*Math.sin(Math.toRadians(i)), 0, radinf*Math.cos(Math.toRadians(i)) ) );
			cono.setCoordinate( 2*i+1, new Point3d( radsup*Math.sin(Math.toRadians(i)), alt, radsup*Math.cos(Math.toRadians(i)) ) );
		}

		for( int i=0; i<359; i++ ){
			cono.setCoordinateIndex( 4*i+0, 2*i+0 );
			cono.setCoordinateIndex( 4*i+1, 2*i+1 );
			cono.setCoordinateIndex( 4*i+2, 2*i+3 );
			cono.setCoordinateIndex( 4*i+3, 2*i+2 );
		}
		cono.setCoordinateIndex( 1440, 718 );
		cono.setCoordinateIndex( 1441, 719 );
		cono.setCoordinateIndex( 1442, 1 );
		cono.setCoordinateIndex( 1443, 0 );

        Color3f c = new Color3f(0.1f, 0.1f, 0.4f);
        for(int i = 0; i < 720; i++) cono.setColor( i, c);

        return new Shape3D(cono);
    }

    public Shape3D crearReticula(double y){
        IndexedLineArray landGeom = new IndexedLineArray(24, GeometryArray.COORDINATES
                                            | GeometryArray.COLOR_3, 56);
        double l = 6;
        double lc = 6*Math.cos(Math.toRadians(45));
        landGeom.setCoordinate( 0, new Point3d(  0, y, l ));
        landGeom.setCoordinate( 1, new Point3d( lc, y,lc ));
        landGeom.setCoordinate( 2, new Point3d(  l, y, 0 ));
        landGeom.setCoordinate( 3, new Point3d( lc, y,-lc));
        landGeom.setCoordinate( 4, new Point3d(  0, y,-l ));
        landGeom.setCoordinate( 5, new Point3d(-lc, y,-lc));
        landGeom.setCoordinate( 6, new Point3d( -l, y, 0 ));
        landGeom.setCoordinate( 7, new Point3d(-lc, y, lc));
		
        l = 4;
        lc = 4*Math.cos(Math.toRadians(45));
        landGeom.setCoordinate( 8, new Point3d(  0, y, l ));
        landGeom.setCoordinate( 9, new Point3d( lc, y,lc ));
        landGeom.setCoordinate(10, new Point3d(  l, y, 0 ));
        landGeom.setCoordinate(11, new Point3d( lc, y,-lc));
        landGeom.setCoordinate(12, new Point3d(  0, y,-l ));
        landGeom.setCoordinate(13, new Point3d(-lc, y,-lc));
        landGeom.setCoordinate(14, new Point3d( -l, y, 0 ));
        landGeom.setCoordinate(15, new Point3d(-lc, y, lc));

        l = 2;
        lc = 2*Math.cos(Math.toRadians(45));
        landGeom.setCoordinate(16, new Point3d(  0, y, l ));
        landGeom.setCoordinate(17, new Point3d( lc, y,lc ));
        landGeom.setCoordinate(18, new Point3d(  l, y, 0 ));
        landGeom.setCoordinate(19, new Point3d( lc, y,-lc));
        landGeom.setCoordinate(20, new Point3d(  0, y,-l ));
        landGeom.setCoordinate(21, new Point3d(-lc, y,-lc));
        landGeom.setCoordinate(22, new Point3d( -l, y, 0 ));
        landGeom.setCoordinate(23, new Point3d(-lc, y, lc));

        landGeom.setCoordinateIndex( 0, 0);
        landGeom.setCoordinateIndex( 1, 4);
        landGeom.setCoordinateIndex( 2, 1);
        landGeom.setCoordinateIndex( 3, 5);
        landGeom.setCoordinateIndex( 4, 2);
        landGeom.setCoordinateIndex( 5, 6);
        landGeom.setCoordinateIndex( 6, 3);
        landGeom.setCoordinateIndex( 7, 7);
        int s = 8;
        for( int p=0;p<24;p+=8 ){
            landGeom.setCoordinateIndex(   s , p  );
            landGeom.setCoordinateIndex( s+1 , p+1);
            landGeom.setCoordinateIndex( s+2 , p+1);
            landGeom.setCoordinateIndex( s+3 , p+2);
            landGeom.setCoordinateIndex( s+4 , p+2);
            landGeom.setCoordinateIndex( s+5 , p+3);
            landGeom.setCoordinateIndex( s+6 , p+3);
            landGeom.setCoordinateIndex( s+7 , p+4);
            landGeom.setCoordinateIndex( s+8 , p+4);
            landGeom.setCoordinateIndex( s+9 , p+5);
            landGeom.setCoordinateIndex( s+10, p+5);
            landGeom.setCoordinateIndex( s+11, p+6);
            landGeom.setCoordinateIndex( s+12, p+6);
            landGeom.setCoordinateIndex( s+13, p+7);
            landGeom.setCoordinateIndex( s+14, p+7);
            landGeom.setCoordinateIndex( s+15, p  );
            s = s+16;
        }
		
/*        LineArray landGeom = new LineArray(132, GeometryArray.COORDINATES
                                            | GeometryArray.COLOR_3);
        double l = -5;
        for(int c = 0; c < 44; c+=4){
            landGeom.setCoordinate( c+0, new Point3d( -5, y,  l ));
            landGeom.setCoordinate( c+1, new Point3d(  5, y,  l ));
            landGeom.setCoordinate( c+2, new Point3d(  l, y, -5 ));
            landGeom.setCoordinate( c+3, new Point3d(  l, y,  5 ));
            l += 1;
        }

		l = y;
        for(int c = 44; c < 88; c+=4){
            landGeom.setCoordinate( c+0, new Point3d( 5,    y, l-(5+y) ));
            landGeom.setCoordinate( c+1, new Point3d( 5, 10+y, l-(5+y) ));
            landGeom.setCoordinate( c+2, new Point3d( 5,    l,      -5 ));
            landGeom.setCoordinate( c+3, new Point3d( 5,    l,       5 ));
            l += 1;
        }

		l = y;
        for(int c = 88; c < 132; c+=4){
            landGeom.setCoordinate( c+0, new Point3d(       -5,    l,  -5 ));
            landGeom.setCoordinate( c+1, new Point3d(        5,    l,  -5 ));
            landGeom.setCoordinate( c+2, new Point3d(  l-(5+y),    y,  -5 ));
            landGeom.setCoordinate( c+3, new Point3d(  l-(5+y), 10-y,  -5 ));
            l += 1;
        }
*/
        Color3f c = new Color3f(0.1f, 0.6f, 0.1f);
        for(int i = 0; i < 24; i++) landGeom.setColor( i, c);

        return new Shape3D(landGeom);
    }

    public void setAngulos(double rot_sup, double inc_sup, double inc_med, double rot_cam){
        pb.setAngulos(rot_sup,inc_sup,inc_med,rot_cam);
    }
    
    public void setSize(int ancho, int alto){
        lienzo3d.setSize(ancho, alto);
    }

}
